#include <windows.h>
#include <commctrl.h>

#include "mmbar.h"
#include "monitors.h"

enum { Count, Info, CreateWindows, FindMonitor };

int num_monitors;
struct Monitor *monitors = 0;

static HMONITOR query;
static struct Monitor *query_result;

static void create_monitors(void);
static void visit_monitors(int);
static BOOL CALLBACK visit_monitor(HMONITOR, HDC, LPRECT, LPARAM);

void init_monitors(void)
{
	if(monitors)
		free_monitors();
	
	create_monitors();
	visit_monitors(Info);
	visit_monitors(CreateWindows);
}

void free_monitors(void)
{
	int i;
	for(i = 0; i < num_monitors; ++i)
	{
		struct Monitor *mon = monitors + i;
		HWND bar = mon->bar;
		
		if(bar)
			SendMessage(bar, WM_CLOSE, 0, 0);
		
		ImageList_Destroy(mon->icons);
	}
	free(monitors);
	monitors = 0;
}

void update_monitor(struct Monitor *mon)
{
	if(mon->tbar)
	{
		TBBUTTON bt;
		HWND wnd;
		int count = SendMessage(mon->tbar, TB_BUTTONCOUNT, 0, 0);
		int i;
		
		for(i = 0; i < count; ++i)
		{
			SendMessage(mon->tbar, TB_GETBUTTON, i, (LPARAM)&bt);
			wnd = (HWND)bt.dwData;
			if(wnd)
				track_window(wnd);
		}
	}
}

struct Monitor *from_hmonitor(HMONITOR hmon)
{
	query = hmon;
	query_result = 0;
	
	visit_monitors(FindMonitor);
	
	return query_result;
}

int is_primary(struct Monitor *mon)
{
	return mon->info.dwFlags & MONITORINFOF_PRIMARY;
}

static void create_monitors(void)
{
	visit_monitors(Count);
	monitors = malloc(num_monitors * sizeof(struct Monitor));
}

static void visit_monitors(int operation)
{
	num_monitors = 0;
	EnumDisplayMonitors(0, 0, &visit_monitor, operation);
}

static BOOL CALLBACK visit_monitor(
	HMONITOR monitor, 
	HDC dc,
	LPRECT rect, 
	LPARAM operation)
{
	struct Monitor *mon = monitors + num_monitors;
	
	if(operation == Info)
	{
		MONITORINFOEX *pinfo = &(mon->info);
		pinfo->cbSize = sizeof(MONITORINFOEX);
		GetMonitorInfo(monitor, (LPMONITORINFO)pinfo);
		
		mon->index = num_monitors;
		mon->hmon = monitor;
		mon->icons = ImageList_Create(16, 16, ILC_COLOR32, 0, 1000);
	}
	else if(operation == CreateWindows)
	{
		if(mon->bar)
			DestroyWindow(mon->bar);
		
		if(is_primary(mon))
		{
			mon->bar = 0;
			mon->tbar = 0;
		}
		else
			create_mmbar(mon);
	}
	else if(operation == FindMonitor)
	{
		if(monitor == query)
			query_result = mon;
	}
	++ num_monitors;
	return TRUE;
}


